<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Auth;

class WeChatController extends Controller
{
    /**
     * Note: 引导用户进入授权页面同意授权，获取code
     * User: 凸^-^凸
     * Date: 2020-10-29 16:43
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\think\response\Redirect
     */
    public function wxCode()
    {
        //一定要按照参数的顺序进行排列，否则接口将无法访问
        $params = http_build_query([
            'appid' => 'wx4d069e2355e28238',
            'redirect_uri'=> 'http://weixin.wjz0098.me/wxtoken',
            'response_type' => 'code',
            'scope' => 'snsapi_userinfo'
        ]);

        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?'.$params .'#wechat_redirect';
        return redirect($url);
    }

    /**
     * Note: 通过code换取网页授权access_token（与基础支持中的access_token不同
     * User: 凸^-^凸
     * Date: 2020-10-29 16:43
     * @param Request $request
     */
    public function wxToken(Request $request)
    {
        $code = $request->input('code');
        $params = http_build_query([
            'appid' => 'wx4d069e2355e28238',
            'secret'=> 'eea3cc3f66a19520cc6dbaa6c899308a',
            'code' => $code,
            'grant_type' => 'authorization_code'
        ]);
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?'.$params;
        $result = json_decode(file_get_contents($url));

        // 3、如果需要，开发者可以刷新网页授权access_token，避免过期（这里只需要根据上面的接口一样进行数据获取即可）
        // 4、通过网页授权access_token和openid获取用户基本信息（支持UnionID机制）
        // dd($result);
        $params = http_build_query([
            'access_token' => $result->access_token,
            'openid' => $result->openid,
            'lang' => 'zh_CN',
        ]);
        $url = 'https://api.weixin.qq.com/sns/userinfo?'.$params;
        $UserInfo = json_decode(file_get_contents($url));
        dd($UserInfo);
    }

    public function auth(Request $request)
    {
        $WeChatUserInfo = session('wechat.oauth_user.default');

        // dd($WeChatUserInfo);
        // exit

        $UserInfo = User::where('Openid',$WeChatUserInfo['id'])->first();

        if (!$UserInfo) {
            //用户的密码需要他在第一次登录的时候进行设置
            //手机号码需要进行绑定,需要根据用户id来进行异构索引表分表
            $result = User::create([
                'id' => $this->uuid(),
                'Openid' => $WeChatUserInfo['id'],
                'username' => $WeChatUserInfo['name'],
                'role_id' => 1,//角色默认1位普通用户
                'vender_type' => 2,
                'status' => 0,
                'login_ip' => $request->getClientIp()
            ]);
        }else{
            $result = $UserInfo;
        }

        //登录验证
        Auth::login($result,true);

        $redirect_url = $request->redirect_url;
        if ($redirect_url == '') {
            // code...
            return \redirect('/products');
        }else{
            return \redirect($redirect_url);
        }
    }

    public function uuid($prefix='')
    {
        // code...
        $str = md5(uniqid(mt_rand(), true));
        $uuid  = substr($str,0,8) . '-';
        $uuid .= substr($str,8,4) . '-';
        $uuid .= substr($str,12,4) . '-';
        $uuid .= substr($str,16,4) . '-';
        $uuid .= substr($str,20,12);
        return $prefix . $uuid;
    }

    protected function checkSignature(Request $request)
    {
        $signature = $request->signature;//签名串
        $timestamp = $request->timestamp;//时间戳
        $nonce = $request->nonce;//随机数

        $token = env('WECHAT_OFFICIAL_ACCOUNT_TOKEN');//微信公众号中定义的
        $tmpArr = array($token, $timestamp, $nonce);
        // use SORT_STRING rule
        sort($tmpArr, SORT_STRING);//排序
        $tmpStr = implode($tmpArr);//生成字符串
        $tmpStr = sha1($tmpStr);//从新生成签名串

        //两次签名比较
        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    public function valid(Request $request)
    {
        $echoStr = $request->echostr;

        if ($this->checkSignature($request)) {
            echo $echoStr;
        }
    }

    public function weChatToken(Request $request)
    {
        if (empty($request->echostr)) {
            $this->responseMsg();
        } else {
            $this->valid($request);//第一次握手,执行一次
        }
    }

    //消息自动回复
    public function responseMsg()
    {
        if (phpversion()<7) {
            //获取来自微信服务器的消息
            $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        } else {//>=7.0
            $postStr = file_get_contents('php://input');
        }


        $request_xml = simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
        $type = $request_xml->MsgType;
        switch ($type) {
            case 'event':
                //判断具体的事件类型（关注、取消、点击）
                $event = $request_xml->Event;
                if ($event == 'subscribe') { // 关注事件
                    $this->_doSubscribe($request_xml);
                } elseif ($event == 'CLICK') {//菜单点击事件
//                        $this->_doClick($request_xml);
                } elseif ($event == 'VIEW') {//连接跳转事件
//                        $this->_doView($request_xml);
                }
                break;
            case 'text'://文本消息
                $this->_doText($request_xml);
                break;
            case 'image'://图片消息
                $this->responseImage($request_xml);
                break;
            case 'voice'://语音消息
                $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段语音');
                break;
            case 'video'://视频消息
                $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段视频');
                break;
            case 'shortvideo'://短视频消息
                $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一段短视频');
                break;
            case 'location'://位置消息
                $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一个位置信息');
                break;
            case 'link'://链接消息
//                    $this->_doLink($request_xml);
                $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, '这是一个链接');
                break;
            default:
                echo "……凸^-^凸";
        }
    }

    private $_msg_template = array(
        'text' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',//文本回复XML模板
        'image' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>',//图片回复XML模板
        'music' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>',//音乐模板
        'news' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>%s</ArticleCount><Articles>%s</Articles></xml>',// 新闻主体
        'news_item' => '<item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>',//某个新闻模板
    );

    /**
     * 发送文本信息
     * @param  [type] $to      目标用户ID
     * @param  [type] $from    来源用户ID
     * @param  [type] $content 内容
     */
    private function _msgText($to, $from, $content)
    {
        $response = sprintf($this->_msg_template['text'], $to, $from, time(), $content);
        die($response);
    }

    //关注后做的事件
    private function _doSubscribe($request_xml)
    {
        //处理该关注事件，向用户发送关注信息
        $content = '你好, 我是车队队长……(^-^)';
        $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    }

    private function _doText($request_xml)
    {
        $content = $request_xml->Content;
        $url = 'http://www.tuling123.com/openapi/api?key='.TULING.'&info='.$content;
        // 引入图灵机器人
        $response_content = json_decode(curl_get($url));
        $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content->text);
    }

    // 回复图片信息
    public function responseImage($obj)
    {
        $msg = "<xml>
			<ToUserName><![CDATA[%s]]></ToUserName>
			<FromUserName><![CDATA[%s]]></FromUserName>
			<CreateTime>%s</CreateTime>
			<MsgType><![CDATA[image]]></MsgType>
			<Image>
			<MediaId><![CDATA[C6eEIuNBwBsbaYF2nKLlND7HU8OMUPKIu8NQp4q_7cnqmd7Ilxf35YIUeknN8PL_]]></MediaId>
			</Image>
			</xml>";
        echo sprintf($msg,$obj->FromUserName,$obj->ToUserName,time().'');
    }

    public function addMenu(Request $request)
    {
        //
        $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$this->getToken();
        $menuData = json_decode($request->menuData,'true');
        echo curl_post($url,$menuData);
    }


    //获取用户基本信息
    public function getUserInfo($openid)
    {
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$this->getToken()."&openid=".$openid."&lang=zh_CN";
        file_put_contents('userinfo.txt', curl_get($url));
    }

    public function getToken(){
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".env('WECHAT_OFFICIAL_ACCOUNT_APPID')."&secret=".env('WECHAT_OFFICIAL_ACCOUNT_SECRET');
        //1 检测是否有本地缓存文件
        if (file_exists('token.txt')) {
            // 判断是否过期
            if (filemtime('token.txt')+7200>time()) {
                $content = file_get_contents('token.txt');
                $obj = json_decode($content);
                return $obj->access_token;
            } else {
                //重新发起请求
                return $this->requireToken($url);
            }
        } else {
            //2 如果没有，直接发起请求，获取access_token，写缓存文件
            return $this->requireToken($url);
        }
    }
    public function requireToken($url)
    {
        $content = curl_get($url);
        file_put_contents('token.txt', $content);
        $obj = json_decode($content);
        return $obj->access_token;
    }
}
